/*
 * BitMap.java
 */

package rehab.host.spotfinder;

/**
 *
 * @author mi zhang
 */
public class BitMap {
    
    private final int numBits;            // number of bits in the bitmap
    private int map[];                    // bit storage
    
    //----------------------------------------------------------------------
    // BitMap::BitMap
    // 	Initialize a bitmap with "nitems" bits, so that every bit is clear.
    //	it can be added somewhere on a list.
    //
    //	"nitems" is the number of bits in the bitmap.
    //----------------------------------------------------------------------
    public BitMap(int nitems) {
        numBits = nitems;
        map = new  int[nitems];
        for (int i = 0; i < numBits; i++) 
            Clear(i);
    }
    
    //----------------------------------------------------------------------
    // BitMap::Clear
    // 	Clear the "nth" bit in a bitmap.
    //
    //	"which" is the number of the bit to be cleared.
    //----------------------------------------------------------------------   
    public void Clear(int which) {
        if (which >=0 && which < numBits)
            map[which] = 0;
    }
    
    //----------------------------------------------------------------------
    // BitMap::Mark
    // 	Set the "nth" bit in a bitmap.
    //
    //	"which" is the number of the bit to be set.
    //----------------------------------------------------------------------
    public void Mark(int which) {
        if (which >=0 && which < numBits)
            map[which] = 1;
    }
    //----------------------------------------------------------------------
    // BitMap::Test
    // 	Return TRUE if the "nth" bit is set.
    //
    //	"which" is the number of the bit to be tested.
    //----------------------------------------------------------------------  
    public boolean Test(int which){
        if (which >=0 && which < numBits) {
            if (map[which] == 1)
                return true;
            else 
                return false;
        }
        return false;
    }
    
    //----------------------------------------------------------------------
    // BitMap::Find
    // 	Return the number of the first bit which is clear.
    //	As a side effect, set the bit (mark it as in use).
    //	(In other words, find and allocate a bit.)
    //
    //	If no bits are clear, return -1.
    //----------------------------------------------------------------------

    public int Find() {
        for (int i = 0; i < numBits; i++)
            if (!Test(i)) {
                Mark(i);
                return i;
            }
        return -1;
    }
    
    
    //----------------------------------------------------------------------
    // BitMap::NumClear
    // 	Return the number of clear bits in the bitmap.
    //	(In other words, how many bits are unallocated?)
    //----------------------------------------------------------------------

    public int NumClear() {
        int count = 0;

        for (int i = 0; i < numBits; i++)
            if (!Test(i)) count++;
        return count;
    }

    //----------------------------------------------------------------------
    // BitMap::Print
    // 	Print the contents of the bitmap, for debugging.
    //
    //	Could be done in a number of ways, but we just print the #'s of
    //	all the bits that are set in the bitmap.
    //----------------------------------------------------------------------

    public void Print() {
        System.out.println("Bitmap set:"); 
        for (int i = 0; i < numBits; i++)
            if (Test(i))
                 System.out.print(i + " ");
    }
}
